package org.one.stone.soup.grfxML.plugin.system;

import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.InputStream;
import java.net.URL;
import java.util.Vector;

import org.one.stone.soup.file.FileHelper;
import org.one.stone.soup.grfxML.DataText;
import org.one.stone.soup.grfxML.GrfxMLEngine;
import org.one.stone.soup.grfxML.plugin.SimplePlugin;
import org.one.stone.soup.grfxML.plugin.grfxMLCaster;
import org.one.stone.soup.mjdb.data.field.DataLinker;
import org.one.stone.soup.stringhelper.StringArrayHelper;

public class DropManager extends SimplePlugin implements DropTargetListener{

	private Vector handlers = new Vector();

	private static final int ARG_LIST = 0;
	private DataText handlerList = new DataText();

/**
 * SuperString constructor comment.
 */
public DropManager(GrfxMLEngine engine){
	super(engine);
}
/**
 * initialize method comment.
 */
public void initialize()
{
	for(int loop=0;loop<handlerList.size();loop++)
	{
		String[] handlers = StringArrayHelper.parseFields(handlerList.get(loop).getValue(),'\n');
		for(int loopH=0;loopH<handlers.length;loopH++)
		{
			String className = handlers[loopH].trim();
			if(className.length()>0)
			{
				addHandler(className);
			}
		}
	}

	new DropTarget(getEngine().getController().getComponent(),this);
}
/**
 * process method comment.
 */
public void process(){}
/**
 * register method comment.
 */
public void register(DataLinker store)
{
	handlerList	=	grfxMLCaster.cast(handlerList,getArg(handlerList,ARG_LIST,store));
}
/**
 * replace method comment.
 */
public void replace(org.one.stone.soup.mjdb.data.field.Field oldObj, org.one.stone.soup.mjdb.data.field.Field newObj)
{
	handlerList		=	grfxMLCaster.replace(handlerList,oldObj,newObj);
}
/**
 * stop method comment.
 */
public void stop()
{
}
	/* (non-Javadoc)
	 * @see java.awt.dnd.DropTargetListener#drop(java.awt.dnd.DropTargetDropEvent)
	 */
	public void drop(DropTargetDropEvent de) {
		de.acceptDrop(de.getDropAction());

		/*DataFlavor[] df = de.getCurrentDataFlavors();
		for(int loop=0;loop<df.length;loop++)
		{
			System.out.println("df:"+df[loop].getClass());
			System.out.println("  name:"+df[loop].getHumanPresentableName());
			System.out.println("  mime:"+df[loop].getMimeType());
			System.out.println("  rep class:"+df[loop].getDefaultRepresentationClassAsString());
		}*/

		try{
			//DataFlavor d = new DataFlavor("text/html");

			DataFlavor d[] = de.getTransferable().getTransferDataFlavors();
			Object transferData = de.getTransferable().getTransferData(d[0]);

			String data = "?";
			if(transferData instanceof InputStream)
			{
				data = new String(FileHelper.readFile( (InputStream)transferData ));
			}
			else if(transferData instanceof URL)
			{
				data = ((URL)transferData).toExternalForm();
			}
			else
			{
				data = transferData.toString();
			}

			if(data.indexOf('[')==0)
			{
				data = data.substring(1,data.length()-1);
			}

			Point point = de.getLocation();

			handle(data,point.x,point.y);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			de.dropComplete(true);
		}
	}

	private void addHandler(String className)
	{
		try{
			DropHandler handler = (DropHandler)Class.forName(className).newInstance();
			handlers.addElement(handler);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	private void handle(String name,int x,int y)
	{
		for(int loop=0;loop<handlers.size();loop++)
		{
			DropHandler handler = (DropHandler)handlers.elementAt(loop);

			if(handler.matches(name,x,y))
			{
				if( handler.handle(name,getEngine(),x,y)==true )
				{
					return;
				}
			}
		}
	}

	public void dropActionChanged(DropTargetDragEvent dtde) {}
	public void dragEnter(DropTargetDragEvent dtde) {}
	public void dragExit(DropTargetEvent dte) {}
	public void dragOver(DropTargetDragEvent dtde) {}

}
